/**
 * 
 */
package dungeon;

import static org.junit.Assert.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;

import org.junit.Before;
import org.junit.Test;

import border.Border;
import border.Door;
import border.Wall;

import square.Direction;
import square.NormalSquare;
import square.Rock;
import square.Square;
import square.TeleportationSquare;
import square.Temperature;
import square.TemperatureScale;
import square.TransparentSquare;

/**
 * @author Inge
 *
 */
public class DungeonTest {

	@Before
	public void setUp() throws Exception {
		cd1 = new ComposedDungeon<Square>(5, 5, 1);
		cd2 = new ComposedDungeon<Square>(5, 5, 0);
		l = new Level<Square>(3, 3, 0);
		s = new Shaft<Square>(3, 0, 0);
		sq1 = new NormalSquare();
		sq2 = new NormalSquare();
		sq3 = new NormalSquare();
		sq4 = new NormalSquare();
		sq5 = new NormalSquare();
		w1 = new Wall(sq1,Direction.SOUTH,false);
		w2 = new Wall(sq2,Direction.SOUTH,false);
		
		l.putDungeonIn(cd2, new Position(1,0,0));
		s.putDungeonIn(cd2, new Position(1,4,0));
		cd2.putDungeonIn(cd1, new Position(0,0,1));
		
		l.addSquare(new Position(1,3,0), sq1);
		cd2.addSquare(new Position(3,3,0),sq2);
		cd1.addSquare(new Position(2, 4, 1), sq3);
		cd1.addSquare(new Position(3,4,1), sq4);
	}
	

	@Test
	public void getSpace_singleCase(){
		HashSet<TeleportationSquare> space = cd1.getSpace(sq1);
		assertTrue(space.contains(sq1));
		assertTrue(space.contains(sq2));
		assertEquals(2,space.size());
	}
	
	@Test
	public void canNavigateTo_extendedCase(){
		cd1.addSquare(new Position(2,0,1),sq5);
		sq2.addTeleportationDestination(sq5);
		sq5.addTeleportationDestination(sq3);
//		sq4 is in the same space as sq3, sq3 is a teleportation
//		destination of sq5, sq5 is a teleportation destination of
//		sq2 and sq2 is in the same space as sq1.
		assertTrue(cd1.canNavigateTo(sq1,sq4));
	}
	
	@Test
	public void canNavigateTo_squareInSameSpace(){
		assertTrue(cd1.canNavigateTo(sq1, sq2));
	}
	
	@Test
	public void canNavigateTo_TeleportationDestination(){
		sq1.addTeleportationDestination(sq3);
		assertTrue(cd1.canNavigateTo(sq1, sq3));
	}
	
	@Test
	public void canNavigateTo_squareInSameSpaceAsTeleportationDestination(){
		sq1.addTeleportationDestination(sq3);
		assertTrue(cd1.canNavigateTo(sq1, sq4));
	}
	
	@Test
	public void canNavigateTo_TeleportationDestinationOfSquareInSameSpace(){
		sq1.addTeleportationDestination(sq3);
		assertTrue(cd1.canNavigateTo(sq2, sq3));
	}
	
	@Test
	public void canNavigateTo_noPath(){
		assertFalse(cd1.canNavigateTo(sq1, sq4));
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void canNavigateTo_illegalArgument(){
		cd1.canNavigateTo(sq1, null);
	}
	
	@Test (expected = IllegalArgumentException.class)
	public void canNavigateTo_illegalStartArgument(){
		sq1.terminate();
		cd1.canNavigateTo(sq1, sq2);
	}
	
	@Test
	public void canNavigateTo_sameSquare(){
		assertTrue(cd1.canNavigateTo(sq2, sq2));
	}
	
	@Test
	public void canNavigateTo_connectedThroughSquareOutsideDungeon(){
		NormalSquare sq6 = new NormalSquare();
		sq1.addTeleportationDestination(sq6);
		sq6.addTeleportationDestination(sq3);
		assertFalse(cd1.canNavigateTo(sq1, sq3));
	}
	
	@Test
	public void getSurroundingRocks_singleCase(){
		Rock r1 = new Rock();
		Rock r2 = new Rock();
		cd1.addSquare(new Position(4,4,1), sq5);
		cd1.addSquare(new Position(2,2,1), r1);
		cd1.addSquare(new Position(4,3,1), r2);
		HashSet<Rock> rocks = cd1.getSurroundingRocks(sq2);
		assertTrue(rocks.contains(r1));
		assertTrue(rocks.contains(r2));
		assertEquals(2, rocks.size());
	}
	
	@Test
	public void mergeSpaces_SingleCase(){
		sq1.setTemperature(new Temperature(50));
		sq2.setTemperature(new Temperature(50));
		Square sq6 = new TransparentSquare(new Temperature(0),new BigDecimal(0),Direction.NORTH);
		((Door) sq6.getBorder(Direction.NORTH)).open();
		cd1.addSquare(new Position(4,3,1), sq5);
		cd1.addSquare(new Position(4,4,1), sq6);
		assertEquals(sq1.getTemperature(), sq4.getTemperature());
	}
	
	@Test
	public void canHavAsContainingDungeon_singleCase(){
		assertFalse(cd1.canHaveAsContainingDungeon(cd2));
	}
	
	@Test
	public void getRootDungeon_singleCase(){
		assertEquals(cd1, s.getRootDungeon());
	}

	ComposedDungeon<Square> cd1;
	ComposedDungeon<Square> cd2;
	Level<Square> l;
	Shaft<Square> s;
	NormalSquare sq1;
	NormalSquare sq2;
	NormalSquare sq3;
	NormalSquare sq4;
	NormalSquare sq5;
	Wall w1;
	Wall w2;
	


}
